package com.ruoyi.fjtseac.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.fjtseac.domain.dto.EssayDto;
import com.ruoyi.fjtseac.domain.po.Photo;
import com.ruoyi.fjtseac.domain.vo.EssayVo;
import com.ruoyi.fjtseac.mapper.EssayMapper;
import com.ruoyi.fjtseac.domain.po.Essay;
import com.ruoyi.fjtseac.mapper.PhotoMapper;
import com.ruoyi.fjtseac.mapper.TypeMapper;
import com.ruoyi.fjtseac.service.EssayService;
import com.ruoyi.fjtseac.service.TypeService;
import com.ruoyi.fjtseac.util.DtoToPoMapper;
import com.ruoyi.fjtseac.util.FileUtil;
import com.ruoyi.fjtseac.util.PoToVoMapper;
import com.ruoyi.fjtseac.util.aop.RedisCacheClear;
import com.ruoyi.fjtseac.util.aop.RedisCacheEnable;
import com.ruoyi.fjtseac.util.aop.TableEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static com.ruoyi.common.utils.PageUtils.startPage;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author jxl
 * @since 2022-07-08
 */
@Service
public class EssayServiceImpl extends ServiceImpl<EssayMapper, Essay> implements EssayService {

    @Value("${cos.host}")
    private String host;
    private final RedisCache redisCache;
    private final EssayMapper essayMapper;
    private final FileUtil fileUtil;
    private final TypeMapper typeMapper;
    private final PhotoMapper photoMapper;

    @Autowired
    public EssayServiceImpl(EssayMapper essayMapper, FileUtil fileUtil, TypeMapper typeMapper, PhotoMapper photoMapper, RedisCache redisCache) {
        this.essayMapper = essayMapper;
        this.photoMapper = photoMapper;
        this.fileUtil = fileUtil;
        this.typeMapper = typeMapper;
        this.redisCache = redisCache;
    }

    @Override
    public AjaxResult addEssay(@NotNull(message = "文章不能为空") EssayDto essayDto) {
        Essay essay = DtoToPoMapper.INSTANCE.toEssay(essayDto);
        essay.setCreateTime(LocalDateTime.now());
        if(typeMapper.selectById(essayDto.getTypeId()) == null) {
            return AjaxResult.error("文章类别不存在，添加失败");
        }

        if(essayMapper.insert(essay)>=1) {
            Photo photo = new Photo();
            photo.setEssayId(essay.getEssayId());
            photo.setPhotoUrl(essay.getCoverUrl());
            photoMapper.insert(photo);
            return AjaxResult.success("上传成功");
        }
        return AjaxResult.error("上传失败");
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public AjaxResult selectById(Integer essayId) {
        Essay essay = essayMapper.selectById(essayId);
        if(essay != null) {
            EssayVo essayVo = PoToVoMapper.INSTANCE.toEssayVo(essay);
            return AjaxResult.success(essayVo);
        }
        return AjaxResult.error();
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public AjaxResult selectAll(Integer pageNum, Integer pageSize) {
        startPage(pageNum, pageSize);
        QueryWrapper<Essay> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("create_time");
        List<Essay> essays = essayMapper.selectList(queryWrapper);
        if(essays.size() == 0) {
            return AjaxResult.error("未编写任何文章");
        }
        List<EssayVo> essayVos = new ArrayList<>();
        for (Essay essay : essays) {
            EssayVo essayVo = PoToVoMapper.INSTANCE.toEssayVo(essay);
            essayVos.add(essayVo);
        }
        return AjaxResult.getPageResult(essays, essayVos);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public AjaxResult selectEssayByType(Integer typeId, Integer pageNum, Integer pageSize) {
        startPage(pageNum, pageSize);
        QueryWrapper<Essay> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type_id", typeId)
                    .orderByDesc("create_time");
        List<Essay> essays = essayMapper.selectList(queryWrapper);
        List<EssayVo> essayVos = new ArrayList<>();
        for (Essay essay : essays) {
            String key = TableEnum.ESSAY.getTableName() + ":" + essay.getEssayId();
            if (redisCache.getCacheObject(key) == null){
                //将浏览量先存入redis，进行数据预热。
                redisCache.setCacheObject(key, essay.getPv());
            }
            EssayVo essayVo = PoToVoMapper.INSTANCE.toEssayVo(essay);
            essayVos.add(essayVo);
        }
        return AjaxResult.getPageResult(essays, essayVos);
    }

    @Override
    public AjaxResult updateEssay(EssayDto essayDto) {
        if( typeMapper.selectById(essayDto.getTypeId()) == null) {
            return AjaxResult.error("不存在该文章类别，修改失败");
        }

        Essay essay = DtoToPoMapper.INSTANCE.toEssay(essayDto);
        essay.setCreateTime(LocalDateTime.now());
        if(essayMapper.updateById(essay) >= 1) {
            return AjaxResult.success("修改成功");
        }
        return AjaxResult.error("修改失败");
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public AjaxResult selectEssayByTime(String startTime, String endTime, Integer typeId ,Integer pageNum, Integer pageSize) {
        startPage(pageNum, pageSize);
        List<Essay> essays = essayMapper.selectEssayByTime(startTime, endTime, typeId);
        if(essays.size() == 0) {
            return AjaxResult.error("该时间段暂无文章编写");
        }
        List<EssayVo> essayVos = new ArrayList<>();
        for (Essay essay : essays) {
            EssayVo essayVo = PoToVoMapper.INSTANCE.toEssayVo(essay);
            essayVos.add(essayVo);
        }
        return AjaxResult.getPageResult(essays, essayVos);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public AjaxResult selectEssayByTitle(String title, Integer pageNum, Integer pageSize) {
        startPage(pageNum, pageSize);
        QueryWrapper<Essay> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("title" , title);
        List<Essay> essays = essayMapper.selectList(queryWrapper);
        if(essays.size() == 0) {
            return AjaxResult.error("查无此文章");
        }
        List<EssayVo> essayVos = new ArrayList<>();
        for (Essay essay : essays) {
            EssayVo essayVo = PoToVoMapper.INSTANCE.toEssayVo(essay);
            essayVos.add(essayVo);
        }
        return AjaxResult.getPageResult(essays, essayVos);
    }

    @Override
    public AjaxResult deleteEssayById(Integer essayId) {
        if(essayMapper.deleteById(essayId) >= 1) {
            QueryWrapper<Photo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("essay_id", essayId);
            Photo photo = photoMapper.selectOne(queryWrapper);
            fileUtil.delete(photo.getPhotoUrl().replaceAll(host + "/", ""));
            photoMapper.delete(queryWrapper);
            return AjaxResult.success("删除成功");
        }
        return AjaxResult.error("删除失败");
    }

    @DataSource(value = DataSourceType.MASTER)
    @Override
    public AjaxResult setCarousel(@NotEmpty(message = "文章id不能为空") Integer... essayIds) {
        int i = essayMapper.setCarousel(essayIds);
        if(i == 0) {
            return AjaxResult.error(Arrays.toString(essayIds) + "中存在数据库中不存在的文章id");
        }
        return AjaxResult.success("设置成功");
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public AjaxResult getCarouselEssays() {
        QueryWrapper<Essay> wrapper = new QueryWrapper<>();
        wrapper.eq("is_carousel", 1);
        List<Essay> essays = essayMapper.selectList(wrapper);
        List<EssayVo> essayVos = new ArrayList<>();
        for (Essay essay : essays) {
            EssayVo essayVo = PoToVoMapper.INSTANCE.toEssayVo(essay);
            essayVos.add(essayVo);
        }
        return AjaxResult.success(essayVos);
    }
}
